home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Tools for Macintosh
/
Power Tools for Macintosh (SoftBit)(1992).iso
/
Applications
/
Alpha 4.01
/
ACMDS
/
acmds.new
/
sort.c
< prev
Wrap
C/C++ Source or Header
|
1991-07-29
|
5KB
|
297 lines
/* Sort ACMD */
#include "MacHeaders"
#include "stdlib.h"
#include "SetUpA4.h"
#define TRUE 1
#define FALSE 0
#define CR '\r'
#undef DEBUG
/* pointer to a function that returns an 'int' */
typedef int (*FPtr)();
/* global variables */
long sortCol = 0;
static char *qBase;
static size_t qSize;
static int (*qCompare)();
static int (*q1Compare)();
static void (*q1Swap)();
static int std_compare(size_t, size_t);
static void std_swap(size_t, size_t);
static void qsort1(size_t, size_t);
static void aqsort(void *, size_t, size_t, int (*)());
FPtr theAlert;
char *
#ifdef DEBUG
sort(text, alert, getVar, setVar, defineVar,deleteVar)
#else
main(text, alert, getVar, setVar, defineVar,deleteVar)
#endif DEBUG
char *text;
FPtr getVar, setVar, defineVar, deleteVar, alert;
{
long lines,i;
register char *ptr, *ptr2;
char **ptrs, *toPtr;
int endingCr = FALSE;
int lineCompare();
#ifndef DEBUG
/* this self-modifying stuff will crash under A/UX... */
RememberA0();
SetUpA4();
if (!getVar("sortColumn", &sortCol))
{
alert("Unable to access vars");
DisposPtr(text);
return NULL;
}
#endif DEBUG
theAlert = alert;
for (ptr = text, lines = 1; *ptr; ptr++) if (*ptr == CR) lines++;
if (*(ptr - 1) == CR)
{
endingCr = TRUE;
lines--;
}
if (!(ptrs = NewPtr(sizeof(char *) * (lines + 1)))) /* extra for an ending cr we don't use */
{
alert("sort: unable to allocate, error %d", MemError());
#ifndef DEBUG
RestoreA4();
#endif DEBUG
return text;
}
ptrs[0] = text;
for (ptr = text, i = 1; *ptr; ptr++)
{
if (*ptr == CR) ptrs[i++] = ptr + 1;
}
*ptr = CR;
aqsort(ptrs, (long)lines, (long)sizeof(char *), lineCompare);
if (!(toPtr = NewPtr(GetPtrSize(text) + 1)))
{
alert("sort: unable to allocate, error %d", MemError());
#ifndef DEBUG
RestoreA4();
#endif DEBUG
return text;
}
for (i = 0, ptr2 = toPtr; i < lines; i++)
{
for (ptr = ptrs[i]; *ptr != CR;)
{
*ptr2++ = *ptr++;
}
*ptr2++ = CR;
}
if (endingCr)
*ptr2++ = 0;
else
*(ptr2 - 1) = 0;
/* paranoia */
if ((ptr2 - toPtr) > GetPtrSize(toPtr))
{
alert("sort: overran bounds!");
}
/* clean up */
DisposPtr(text);
#ifndef DEBUG
RestoreA4();
#endif DEBUG
return toPtr;
}
/* return first minus second */
lineCompare(sptr1, sptr2)
char **sptr1, **sptr2;
{
register char *ptr1 = *sptr1, *ptr2 = *sptr2;
int i;
for (i = 0; i < sortCol; i++)
{
if (*ptr1++ == CR)
{
return (*ptr2 == CR) ? 0 : -1;
}
if (*ptr2++ == CR)
{
return (1);
}
}
for (; *ptr1 != CR; ptr1++, ptr2++)
{
if (*ptr1 != *ptr2)
{
if (*ptr2 == CR)
{
return (1);
}
else
{
return (*ptr1 - *ptr2);
}
}
}
return ((*ptr2 == CR) ? 0 : -1);
}
#ifdef DEBUG
main()
{
char *text = "one\rtwo\rthree\r";
char *ptr;
ptr = NewPtr(200);
memmove(ptr, text, (long)(strlen(text) + 1));
ptr = sort(ptr);
printf("Result: '%s'\n",ptr);
}
#endif DEBUG
/*
* qsort.c
*
* Copyright (c) 1989 Symantec Corporation. All rights reserved.
*
*/
/* ---------- standard quicksort ---------- */
void
aqsort(base, n, size, compare)
void *base;
size_t n, size;
int (*compare)();
{
qBase = base;
qSize = (size + 1) & ~1;
qCompare = compare;
_aqsort(n, std_compare, std_swap);
}
static int
std_compare(i, j)
size_t i, j;
{
return((*qCompare)(qBase + i * qSize, qBase + j * qSize));
}
static void
std_swap(i, j)
size_t i, j;
{
register void *p = qBase + i * qSize;
register void *q = qBase + j * qSize;
asm {
move.l qSize,d0
@1 move.b (p)+,d1
eor.b d1,(q)+
subq.l #1,d0
bne.s @1
}
asm {
move.l qSize,d0
@2 move.b -(q),d1
eor.b d1,-(p)
subq.l #1,d0
bne.s @2
}
asm {
move.l qSize,d0
@3 move.b (p)+,d1
eor.b d1,(q)+
subq.l #1,d0
bne.s @3
}
}
/* ---------- general quicksort ---------- */
int
_aqsort(n, compare, swap)
size_t n;
int (*compare)();
void (*swap)();
{
q1Compare = compare;
q1Swap = swap;
qsort1(0, n);
}
/*
* sort elements "first" through "last"-1
*
*/
static void
qsort1(first, last)
size_t first, last;
{
static size_t i; /* "static" to save stack space */
size_t j;
while (last - first > 1) {
i = first;
j = last;
for (;;) {
while (++i < last && (*q1Compare)(i, first) < 0)
;
while (--j > first && (*q1Compare)(j, first) > 0)
;
if (i >= j)
break;
(*q1Swap)(i, j);
}
if (j == first) {
++first;
continue;
}
(*q1Swap)(first, j);
if (j - first < last - (j + 1)) {
qsort1(first, j);
first = j + 1; /* qsort1(j + 1, last); */
}
else {
qsort1(j + 1, last);
last = j; /* qsort1(first, j); */
}
}
}